from typing import List
from fastapi import FastAPI, Request, Form, HTTPException, Depends
from fastapi.responses import HTMLResponse, FileResponse, RedirectResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from pathlib import Path
from pydantic import BaseModel
from urllib.parse import unquote
from fastapi.middleware.cors import CORSMiddleware


app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


MUSIC_DIR = Path("music")
USERNAME = "xiaojuzi"
PASSWORD = "123456"

templates = Jinja2Templates(directory="templates")
app.mount("/static", StaticFiles(directory="static"), name="static")


class MusicList(BaseModel):
    dirs: List[str]
    files: List[str]


def verify_user(request: Request):
    auth = request.cookies.get("auth")
    if auth != "ok":
        raise HTTPException(status_code=401)
    return True


@app.get("/api/music/{path:path}", response_model=MusicList)
def browse_music_api(path: str = "", auth: bool = Depends(verify_user)):
    path = unquote(path)
    base = MUSIC_DIR / path
    if not base.exists() or not base.is_dir():
        raise HTTPException(status_code=404, detail="Path not found or not a directory")

    dirs = sorted([p.name for p in base.iterdir() if p.is_dir()])
    files = sorted([p.name for p in base.iterdir() if p.is_file() and p.suffix.lower() in [".flac", ".mp3", ".wav"]])
    return MusicList(dirs=dirs, files=files)


@app.get("/", response_class=HTMLResponse)
def login_page(request: Request):
    return templates.TemplateResponse("login.html", {"request": request})


@app.post("/login")
def login(request: Request, username: str = Form(...), password: str = Form(...)):
    if username == USERNAME and password == PASSWORD:
        response = RedirectResponse("/music", status_code=303)
        response.set_cookie("auth", "ok")
        return response
    return templates.TemplateResponse(
        "login.html", {"request": request, "error": "用户名或密码错误"}
    )


@app.get("/music", response_class=HTMLResponse)
@app.get("/music/{path:path}", response_class=HTMLResponse)
def browse_music(request: Request, path: str = "", auth: bool = Depends(verify_user)):
    path = unquote(path)
    base = MUSIC_DIR / path
    if not base.exists():
        raise HTTPException(status_code=404, detail="路径不存在")

    if base.is_dir():
        dirs = sorted([p.name for p in base.iterdir() if p.is_dir()])
        files = sorted([p.name for p in base.iterdir() if p.is_file() and p.suffix.lower() in [".flac", ".mp3", ".wav"]])
        parent = "/".join(path.split("/")[:-1])
        return templates.TemplateResponse(
            "index.html",
            {"request": request, "dirs": dirs, "files": files, "path": path, "parent": parent},
        )
    else:
        raise HTTPException(status_code=400, detail="不是目录")


@app.get("/file/{path:path}")
def get_music_file(path: str, auth: bool = Depends(verify_user)):
    path = unquote(path)
    file_path = MUSIC_DIR / path
    if not file_path.exists():
        raise HTTPException(status_code=404, detail="File not found")
    mime = {
        ".flac": "audio/flac",
        ".wav": "audio/wav",
        ".mp3": "audio/mpeg"
    }.get(file_path.suffix.lower(), "application/octet-stream")
    return FileResponse(file_path, media_type=mime)


@app.get("/lrc/{path:path}")
def get_lrc(path: str):
    path = unquote(path)
    song_path = MUSIC_DIR / path
    # 尝试先找同名 lrc 文件
    lrc_path = song_path.with_suffix(".lrc")
    if not lrc_path.exists():
        # 尝试 album/lrc/ 下
        lrc_path = song_path.parent / "lrc" / (song_path.stem + ".lrc")

    if lrc_path.exists():
        text = lrc_path.read_text(encoding="utf-8", errors="ignore")
        print(f"[DEBUG] ✅ 找到歌词文件: {lrc_path}")
        print(f"[DEBUG] 歌词内容预览:\n{text[:200]}...")
        return JSONResponse({"lyrics": text})
    else:
        print(f"[DEBUG] ❌ 未找到歌词文件: {lrc_path}")
        return JSONResponse({"lyrics": ""})